package com.maxima.attendance.daos;

import java.util.ArrayList;
import java.util.Date;
import java.util.List;

import org.hibernate.Criteria;
import org.hibernate.HibernateException;
import org.hibernate.Session;
import org.hibernate.criterion.Order;
import org.hibernate.criterion.Restrictions;

import com.maxima.attendance.pojos.TimeLog;
import com.maxima.attendance.pojos.User;
import com.maxima.attendance.utils.DateOperations;
import com.maxima.attendance.utils.HibernateUtils;

public class TimeLogDAO {
	public static void main(String[] args) {
		List<Integer> lst = new ArrayList<Integer>();
		lst.add(1);
		lst.add(2);
		lst.add(3);
		lst.add(4);
		// new TimeLogDAO().setWorkFromHome(lst, true, new Date());
		System.out.println(new TimeLogDAO().getLastTimeLog(3).getRecordDate());
	}

	@SuppressWarnings("unchecked")
	public TimeLog getTimeLogByDate(Integer userId, Date date) {
		Session session = HibernateUtils.getSession();
		session.beginTransaction();
		Criteria criteria = session.createCriteria(TimeLog.class);
		System.out.println(DateOperations.setZeroTime(date));
		criteria.add(Restrictions.eq("recordDate", DateOperations.setZeroTime(date)));
		criteria.add(Restrictions.eq("userId", userId));
		List<TimeLog> timeLogs = (List<TimeLog>) criteria.list();
		session.close();
		if (timeLogs != null && !timeLogs.isEmpty()) {
			return timeLogs.get(0);
		}
		return null;
	}

	@SuppressWarnings("unchecked")
	public TimeLog getLastTimeLog(Integer userId) {
		Session session = HibernateUtils.getSession();
		session.beginTransaction();
		session.clear();
		Criteria currentDatecriteria = session.createCriteria(TimeLog.class);
		currentDatecriteria.add(Restrictions.eq("recordDate", DateOperations.setZeroTime(new Date())));
		currentDatecriteria.add(Restrictions.eq("userId", userId));
		currentDatecriteria.addOrder(Order.desc("id"));
		List<TimeLog> timeLogs = (List<TimeLog>) currentDatecriteria.list();
		if (timeLogs == null || timeLogs.isEmpty()) {
			Criteria lastLoggedinCriteria = session.createCriteria(TimeLog.class);
			lastLoggedinCriteria.add(Restrictions.eq("userId", userId));
			lastLoggedinCriteria.add(Restrictions.isNull("logoutTime"));
			lastLoggedinCriteria.add(Restrictions.isNotNull("loginTime"));
			lastLoggedinCriteria.addOrder(Order.desc("id"));
			lastLoggedinCriteria.setCacheable(false);
			timeLogs = (List<TimeLog>) lastLoggedinCriteria.list();
		}
		session.getTransaction().commit();
		session.close();
		if (timeLogs != null && !timeLogs.isEmpty()) {
			return timeLogs.get(0);
		}
		return null;
	}

	public TimeLog addTimeOut(Integer id, Date logoutTime) {
		Session session = HibernateUtils.getSession();
		session.beginTransaction();
		TimeLog timeLog = null;
		try {
			timeLog = (TimeLog) session.createQuery("select t from TimeLog t where t.id=" + id).uniqueResult();
			timeLog.setLogoutTime(logoutTime);
			session.save(timeLog);
		}
		catch (HibernateException e) {
			e.printStackTrace();
			session.getTransaction().rollback();
		}
		session.getTransaction().commit();
		session.close();
		return timeLog;
	}

	public void addNewTimeLog(TimeLog timeLog) {
		Session session = HibernateUtils.getSession();
		session.beginTransaction();
		try {
			session.save(timeLog);
		}
		catch (HibernateException e) {
			e.printStackTrace();
			session.getTransaction().rollback();
		}
		session.getTransaction().commit();
		session.close();
	}

	public void deleteTimeLog(TimeLog timeLog) {
		Session session = HibernateUtils.getSession();
		session.beginTransaction();
		try {
			session.delete(timeLog);
		}
		catch (HibernateException e) {
			e.printStackTrace();
			session.getTransaction().rollback();
		}
		session.getTransaction().commit();
		session.close();
	}

	@SuppressWarnings("unchecked")
	public void setWorkFromHome(List<Integer> ids, Boolean status, Date date) {
		setAllWorkFromHomeFalse(date);
		if (!ids.isEmpty()) {
			Session session = HibernateUtils.getSession();
			session.beginTransaction();
			Criteria criteria = session.createCriteria(TimeLog.class);
			criteria.add(Restrictions.eq("recordDate", DateOperations.setZeroTime(date)));
			criteria.add(Restrictions.in("userId", ids));
			List<TimeLog> timeLogs = (List<TimeLog>) criteria.list();
			List<Integer> newIds = new ArrayList<Integer>();
			if (timeLogs != null && !timeLogs.isEmpty()) {
				for (TimeLog timeLog : timeLogs) {
					timeLog.setWorkFromHome(status);
					if (status) {
						timeLog.setComment("Work from home");
					} else {
						timeLog.setComment("none");
					}
					newIds.add(timeLog.getUserId());
					session.update(timeLog);
					System.out.println("create old ids");
				}
			}
			ids.removeAll(newIds);
			System.out.println("create new ids");
			for (Integer id : ids) {
				TimeLog timeLog = new TimeLog(date, id, "Work from home");
				timeLog.setWorkFromHome(true);
				session.save(timeLog);
			}
			session.getTransaction().commit();
			session.close();
		}
	}

	@SuppressWarnings("unchecked")
	private void setAllWorkFromHomeFalse(Date date) {
		Session session = HibernateUtils.getSession();
		session.beginTransaction();
		Criteria criteria = session.createCriteria(TimeLog.class);
		criteria.add(Restrictions.eq("recordDate", DateOperations.setZeroTime(date)));
		criteria.add(Restrictions.eq("workFromHome", true));
		List<TimeLog> timeLogs = (List<TimeLog>) criteria.list();
		if (timeLogs != null && !timeLogs.isEmpty()) {
			for (TimeLog timeLog : timeLogs) {
				if (timeLog.getLoginTime() == null) {
					session.delete(timeLog);
				} else {
					timeLog.setWorkFromHome(false);
					timeLog.setComment("none");
					session.update(timeLog);
				}
			}
		}
		session.getTransaction().commit();
		session.close();
	}

	@SuppressWarnings("unchecked")
	public List<User> getUsersWorkingFromHomeByDate(Date date) {
		Session session = HibernateUtils.getSession();
		session.beginTransaction();
		Criteria criteria = session.createCriteria(TimeLog.class);
		criteria.add(Restrictions.eq("recordDate", DateOperations.setZeroTime(date)));
		criteria.addOrder(Order.desc("id"));
		criteria.add(Restrictions.eq("workFromHome", true));
		List<User> users = (List<User>) criteria.list();
		session.getTransaction().commit();
		session.close();
		return users;
	}

	@SuppressWarnings("unchecked")
	public List<TimeLog> getTimeLogsForMonth(Date date) {
		Session session = HibernateUtils.getSession();
		session.beginTransaction();
		Criteria criteria = session.createCriteria(TimeLog.class);
		criteria.add(Restrictions.between("recordDate", DateOperations.setZeroTime(DateOperations.getFirstDateOfMonth(date)), DateOperations.setZeroTime(DateOperations.getLastDateOfMonth(date))));
		List<TimeLog> timeLogs = (List<TimeLog>) criteria.list();
		session.getTransaction().commit();
		session.close();
		return timeLogs;
	}
}
